// Fill out your copyright notice in the Description page of Project Settings.

#include "SimpleWeapon.h"
#include "SimpleProjectile.h"
#include "Kismet/GameplayStatics.h"
#include "Sound/SoundCue.h"
#include "GameFramework/ProjectileMovementComponent.h"
#include "Kismet/KismetSystemLibrary.h"
#include "Net/UnrealNetwork.h"



// Sets default values
ASimpleWeapon::ASimpleWeapon()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = true;

	SceneComponent = CreateDefaultSubobject<USceneComponent>(TEXT("SceneComponent"));
	RootComponent = SceneComponent;

	bIsCanFire = true;
	bReplicates = true;

}

// Called when the game starts or when spawned
void ASimpleWeapon::BeginPlay()
{
	Super::BeginPlay();
	
}

void ASimpleWeapon::ReSetFireCD()
{
	bIsCanFire = true;
	GetWorldTimerManager().ClearTimer(TimerHandle_Fire);
}

void ASimpleWeapon::ServerUpdateProjectile_Implementation(int32 Damage, float ShootSpeed)
{
	UpdateProjectile(Damage, ShootSpeed);
}

bool ASimpleWeapon::ServerUpdateProjectile_Validate(int32 Damage, float ShootSpeed)
{
	return true;
}

void ASimpleWeapon::ServerStopFire_Implementation()
{
	StopFire();
}

bool ASimpleWeapon::ServerStopFire_Validate()
{
	return true;
}

void ASimpleWeapon::ServerStartFire_Implementation()
{
	StartFire();
}

bool ASimpleWeapon::ServerStartFire_Validate()
{
	return true;
}

// Called every frame
void ASimpleWeapon::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);

}

void ASimpleWeapon::StartFire()
{
	if (!bIsCanFire) return;
	if (Role < ROLE_Authority)
	{
		ServerStartFire();
	}
	OnFire();
}

void ASimpleWeapon::StopFire()
{
	if (Role < ROLE_Authority)
	{
		ServerStopFire();
	}
}

void ASimpleWeapon::OnFire()
{
	
	if (HasAuthority())
	{
		FActorSpawnParameters SpawnInfo;
		SpawnInfo.Owner = GetOwner();
		SpawnInfo.Instigator = GetInstigator();
		SpawnInfo.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
		ASimpleProjectile* SimpleProjectile = GetWorld()->SpawnActor<ASimpleProjectile>(DefaultProjectileClass, GetActorTransform(), SpawnInfo);
		if (SimpleProjectile) SimpleProjectile->ProjectileConfig = WeaponData.ProjectileData;
		
		/*
		AActor* BeginSimpleProjectile = UGameplayStatics::BeginDeferredActorSpawnFromClass(this, DefaultProjectileClass, GetActorTransform(), ESpawnActorCollisionHandlingMethod::AlwaysSpawn, GetOwner());
		UKismetSystemLibrary::SetFloatPropertyByName(BeginSimpleProjectile, FName(TEXT("ProjectileSpeed")), 50000.f);
		ASimpleProjectile* EndSimpleProjectile = CastChecked<ASimpleProjectile>(UGameplayStatics::FinishSpawningActor(BeginSimpleProjectile, GetActorTransform()), ECastCheckedType::NullAllowed);
		*/
	}
	if (GetNetMode() != NM_DedicatedServer && ShootSound)
	{
		UGameplayStatics::PlaySoundAtLocation(this, ShootSound, GetActorLocation());
	}
	bIsCanFire = false;
	GetWorldTimerManager().SetTimer(TimerHandle_Fire, this, &ASimpleWeapon::ReSetFireCD, WeaponData.ShootSpeed, false);
}

void ASimpleWeapon::UpdateProjectile(int32 Damage, float ShootSpeed)
{

	if (Role < ROLE_Authority)
	{
		ServerUpdateProjectile(Damage,ShootSpeed);
		return;
	}

	Damage = FMath::Clamp(Damage, -100, 100);
	ShootSpeed = FMath::Clamp(ShootSpeed, -1.f, 0.99f);

	WeaponData.ProjectileData.ExplosionDamage += Damage;
	WeaponData.ShootSpeed *= (1.f - ShootSpeed);
}

void ASimpleWeapon::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	DOREPLIFETIME(ASimpleWeapon, WeaponData);
}

